package cn.touna.jss.modules.third.jzg;

import cn.touna.risk.api.enums.SystemErrorCodeEnum;
import cn.touna.jss.common.factory.ResponseFactory;
import cn.touna.jss.common.properties.disconf.JingzhenguProperties;
import cn.touna.jss.modules.adapter.ApiMapping;
import cn.touna.jss.modules.custom.carmodel.synctask.EncryptUtil;
import cn.touna.jss.modules.third.jzg.entity.JzgRequestEntity;
import cn.touna.risk.api.domain.Response;
import com.alibaba.fastjson.JSONObject;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpEntity;
import org.springframework.http.HttpHeaders;
import org.springframework.http.MediaType;
import org.springframework.stereotype.Service;
import org.springframework.util.LinkedMultiValueMap;
import org.springframework.util.MultiValueMap;
import org.springframework.web.client.RestTemplate;

import javax.annotation.Resource;
import java.security.MessageDigest;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.Base64;

/**
 * Created by hujinhui on 2017/7/28.
 */
@Service
public class JingZhenGuService {

    private static final Logger logger = LoggerFactory.getLogger(JingZhenGuService.class);

    private DateTimeFormatter dateTimeFormatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
    /**
     * 车辆类别：vehicleClassification（可选）0 所有；1 乘用车，int 类型
     */
    private int vehicleClassification = 1;
    /**
     * 销售状态：produceStatus（可选）产销状态 0 所有；1 在销 不传查所有，int 类型
     */
    private int produceStatus = 0;
    /**
     * 是否可估值：isEstimate（可选）是否可估值（0 所有 1 是）,int 类型
     */
    private int isEstimate = 0;
    /**
     * 是否包含电动车：includeElectrombile(0:不包含电动车；1:包含电动车)（可选），int 类型
     */
    private int includeElectrombile = 0;

    @Autowired
    private JingzhenguProperties config;

    @Resource(name = "httpRestTemplate")
    private RestTemplate restTemplate;

    @ApiMapping(value="jingzhengu.estimate",desc="精真估.estimate")
    public Response estimate(JzgRequestEntity.CarPriceRequest carPriceRequest) {
        JSONObject body = new JSONObject();
        body.put("TrimId", carPriceRequest.getTrimId());
        body.put("BuyCarDate", carPriceRequest.getBuyCarDate());
        body.put("Mileage", carPriceRequest.getMileage());
        body.put("CityId", carPriceRequest.getCityId());
//        return queryMessage(body.toJSONString(), "Estimate");
        try {
            JSONObject result = call(config.getUrl(), body.toJSONString());
            if (0 == result.getInteger("errorCode")) {
                result.put("body", JSONObject.parseObject(result.getString("body")));
                return ResponseFactory.success(result);
            } else {
                String errorMessage = result.getString("errorMessage");
                logger.error("精真估估值请求失败", errorMessage);
                return ResponseFactory.fail(SystemErrorCodeEnum.JSS_EXTSYSTEM_RESP_ERROR, errorMessage,result);
            }
        } catch (Exception e) {
            return ResponseFactory.fail(SystemErrorCodeEnum.JSS_CALL_EXTSYSTEM_ERROR, e.getMessage());
        }
    }

    /**
     * 获取车品牌
     *
     * @return
     */
    public JSONObject getMakeByAll() throws Exception {
        JSONObject body = new JSONObject();
        body.put("vehicleClassification", vehicleClassification);
        body.put("isEstimate", isEstimate);
        body.put("produceStatus", produceStatus);
        body.put("includeElectrombile", includeElectrombile);
        return call(config.getGetMakeByAllUrl(), body.toJSONString());
    }

    /**
     * 获取车系
     *
     * @param makeId
     * @return
     */
    public JSONObject getModels(long makeId) throws Exception {
        JSONObject body = new JSONObject();
        body.put("makeId", makeId);
        body.put("vehicleClassification", vehicleClassification);
        body.put("produceStatus", produceStatus);
        body.put("isEstimate", isEstimate);
        return call(config.getGetModelsUrl(), body.toJSONString());
    }

    /**
     * 获取车型
     *
     * @param modelId
     * @return
     */
    public JSONObject getStyles(long modelId) throws Exception {
        JSONObject body = new JSONObject();
        body.put("modelId", modelId);
        body.put("vehicleClassification", vehicleClassification);
        body.put("produceStatus", produceStatus);
        return call(config.getGetStylesUrl(), body.toJSONString());
    }

    private JSONObject call(String url, String body) throws Exception {
        JSONObject req = new JSONObject();
        String sequenceId = LocalDateTime.now().format(dateTimeFormatter);

        String encryptBody = encryptionBody(body);
        req.put("sequenceId", sequenceId);
        req.put("partnerId", config.getPartnerId());
        req.put("operate", "");
        req.put("sign", makeSign(sequenceId, config.getPartnerId(), "", encryptBody, config.getKey()));
        req.put("body", encryptBody);

        HttpHeaders headers = new HttpHeaders();
        headers.setContentType(MediaType.APPLICATION_FORM_URLENCODED);
        MultiValueMap<String, String> map = new LinkedMultiValueMap<String, String>();
        map.add("json", req.toJSONString());
        System.out.println("---------------------------------");
        System.out.println("req: " + req.toJSONString());
        HttpEntity<MultiValueMap<String, String>> request = new HttpEntity<MultiValueMap<String, String>>(map, headers);

        String res = restTemplate.postForObject(url, request, String.class);
        try {
            JSONObject resObj = JSONObject.parseObject(res);
            int errorCode = resObj.getInteger("errorCode");
            if (errorCode != 0) {
                return resObj;
            }
            String resEncryptBody = resObj.getString("body");
            String resBody = EncryptUtil.getDecodeBodyMessage(resEncryptBody, config.getKey());
            resObj.put("body", resBody);
            return resObj;
        } catch (Exception e) {
            logger.error("调用精真估接口异常", e);
            throw e;
        }
    }

    private String encryptionBody(String body) {
        try {
            return EncryptUtil.getBodyEncryption(config.getKey(), body);
        } catch (Exception e) {
            logger.error("精真估加密body异常，", e);
        }
        return "";
    }

    private String makeSign(String sequenceId, String partnerId, String operate, String encryptBody, String key) {
        String str = new StringBuilder().append(sequenceId).append(partnerId).append(operate).append(encryptBody).append(key).toString();
        String res = Base64.getEncoder().encodeToString(EncryptUtil.MD5(str));
        return res;
    }

    public final static byte[] MD5(String str) {
        try {
            byte[] res = str.getBytes("UTF-8");
            MessageDigest mdTemp = MessageDigest.getInstance("MD5".toUpperCase());
            mdTemp.update(res);
            byte[] hash = mdTemp.digest();
            return hash;
        } catch (Exception e) {
            return null;
        }
    }
}
